package demo.using.threadPool;

import java.util.concurrent.*;

/**
 * @author : GuoFei
 * @since : 2019/7/6 10:03
 */
public class TestMain7 {

    //    1、线程池信息： 核心线程数量5，最大数量10，无界队列，超出核心线程数量的线程存活时间：5秒， 无拒绝策略
    // 15个任务，不会使用10个线程去跑，因为等待任务数没有填满队列
    private void test1() throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue());
        testTeak(threadPoolExecutor);
    }

    //    2、线程池信息： 核心线程数量5，最大数量10，队列长度3，超出核心线程数量的线程存活时间：5秒， 指定拒绝策略的
    // 15个任务，最多可以接收13个任务，等待任务数超过队列，会使用最大线程数去运行，然后会有2个任务被拒接
    private void test2() throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS,
                new LinkedBlockingQueue(3), (r, executor) -> System.err.println("mission has been refuse"));
        testTeak(threadPoolExecutor);
    }

    //    3、 线程池信息： 核心线程数量5，最大数量5，无界队列，超出核心线程数量的线程存活时间：0秒
    private void test3() throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
        testTeak(threadPoolExecutor);
    }

    //    4.核心线程数量0，最大数量Integer.MAX_VALUE，SynchronousQueue队列，超出核心线程数量的线程存活时间：60秒
    private void test4() throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<>());
        testTeak(threadPoolExecutor);
        Thread.sleep(60000L);
        System.out.println("60s later , count number in threadPool: " + threadPoolExecutor.getPoolSize());
    }

    //    5.定时执行线程池信息：3秒后执行，一次性任务，到点就执行
    private void test5() {
        ScheduledThreadPoolExecutor threadPoolExecutor = new ScheduledThreadPoolExecutor(5);
        threadPoolExecutor.schedule(() -> System.out.println("mission have run : " + System.currentTimeMillis()), 3, TimeUnit.SECONDS);
        System.out.println("mission has submit success: " + System.currentTimeMillis());
        System.out.println("count threadPool thread number: " + threadPoolExecutor.getPoolSize());
    }


    // 6.以固定时间作为延迟的计划，间隔时间1秒，如果上次任务大于1秒，则会在完成后立刻触发
    private void test6() {
        ScheduledThreadPoolExecutor threadPoolExecutor = new ScheduledThreadPoolExecutor(5);
        threadPoolExecutor.scheduleAtFixedRate(() -> {
            System.out.println("mission have run : " + System.currentTimeMillis());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, 3, 1, TimeUnit.SECONDS);
    }


    // 7.具有固定延迟的计划，间隔时间1秒，但会在完成上次任务3秒的基础上再去延迟1秒
    private void test7() {
        ScheduledThreadPoolExecutor threadPoolExecutor = new ScheduledThreadPoolExecutor(5);
        threadPoolExecutor.scheduleWithFixedDelay(() -> {
            System.out.println("mission have run : " + System.currentTimeMillis());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, 3, 1, TimeUnit.SECONDS);

    }

    // 8. 终止线程 线程池信息： 核心线程数量5，最大数量10，队列大小3，超出核心线程数量的线程存活时间：5秒， 指定拒绝策略的
    private void test8() throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), (r, executor) -> System.err.println("mission has refuse"));
        for (int i = 0; i < 15; i++) {
            int n = i;
            threadPoolExecutor.submit(() -> {
                try {
                    System.out.println("begin run :" + n);
                    Thread.sleep(3000L);
                    System.err.println("end run :" + n);
                } catch (InterruptedException e) {
                    System.out.println("exception :" + e.getMessage());
                }
            });
            System.out.println("mission has submit success :" + i);
        }

        // 1秒后终止线程池
        Thread.sleep(1000L);
        // 终止线程，会等待所有任务进行完成，但不再接收新任务
        threadPoolExecutor.shutdown();
        // 再次提交提示失败
        threadPoolExecutor.submit(() -> System.out.println("add a new mission"));

    }


    // 8. 终止线程
    private void test9() throws InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), (r, executor) -> System.err.println("mission has refuse"));
        for (int i = 0; i < 15; i++) {
            int n = i;
            threadPoolExecutor.submit(() -> {
                try {
                    System.out.println("begin run :" + n);
                    Thread.sleep(3000L);
                    System.err.println("end run :" + n);
                } catch (InterruptedException e) {
                    System.out.println("exception :" + e.getMessage());
                }
            });
            System.out.println("mission has submit success :" + i);
        }

        // 1秒后终止线程池
        Thread.sleep(1000L);
        // 会终止所有进行中的任务，并会抛出InterruptedException异常，并且不再接收新任务
        threadPoolExecutor.shutdownNow();
        // 再次提交提示失败
        threadPoolExecutor.submit(() -> System.out.println("追加一个任务"));

    }


    private void testTeak(ThreadPoolExecutor threadPoolExecutor) throws InterruptedException {
        for (int i = 0; i < 15; i++) {
            int n = i;
            threadPoolExecutor.submit(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + "\tbegin run: " + n);
                    Thread.sleep(3000);
                    System.err.println(Thread.currentThread().getName() + "\tend run: " + n);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            System.out.println(Thread.currentThread().getName() + "\tmission submit success : " + n);
        }
        Thread.sleep(500);
        System.out.println("count threadPool now thread number: " + threadPoolExecutor.getPoolSize());
        System.out.println("count threadPool wait thread number: " + threadPoolExecutor.getQueue().size());
        Thread.sleep(15000);
        System.out.println("count threadPool now thread number: " + threadPoolExecutor.getPoolSize());
        System.out.println("count threadPool wait thread number: " + threadPoolExecutor.getQueue().size());
    }


    public static void main(String[] args) throws InterruptedException {

        // 1、线程池信息： 核心线程数量5，最大数量10，无界队列，超出核心线程数量的线程存活时间：5秒， 无拒绝策略
        new TestMain7().test1();
        // 2、线程池信息： 核心线程数量5，最大数量10，队列长度3，超出核心线程数量的线程存活时间：5秒， 指定拒绝策略的
        new TestMain7().test2();
        // 线程池信息： 核心线程数量5，最大数量5，无界队列，超出核心线程数量的线程存活时间：0秒
        new TestMain7().test3();
        // 核心线程数量0，最大数量Integer.MAX_VALUE，SynchronousQueue队列
        new TestMain7().test4();
        // 定时延迟后执行任务
        new TestMain7().test5();
        // 以固定时间作为延迟的计划，上次任务完成后，延长动态时长后执行
        new TestMain7().test6();
        // 具有固定延迟的计划，上次任务完成后，在延迟固定时长后执行
        new TestMain7().test7();
        // 等待任务结束再关闭线程池
        new TestMain7().test8();
        // 强制关闭线程池，所有进行中线程都会报异常
        new TestMain7().test9();
    }

}
